/*
 * Copyright (c) 2021 Huawei Device Co.,  Ltd.
 * Licensed under the Apache License,  Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,  software
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,  either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "recptprinter_srv_stub.h"
#include <string.h>
#include "message_option.h"
#include "message_parcel.h"
#include "recptprinter_hilog.h"
#include "recptprinter_common.h"
#include "recptprinter_errors.h"
#include "recptprinter_observer_proxy.h"

namespace SwanLink {
namespace Finance {
int RecptprinterSrvStub::OnRemoteRequest(uint32_t code,  MessageParcel& data,
    MessageParcel& reply,  MessageOption& option) {
    RECPTPRINTER_HILOGD(RECPTPRINTER_SRV,  "cmd = %{public}d,  flags = %{public}d",  code,  option.GetFlags());
    std::u16string descriptor = RecptprinterSrvStub::GetDescriptor();
    std::u16string remoteDescriptor = data.ReadInterfaceToken();
    if (descriptor != remoteDescriptor) {
        RECPTPRINTER_HILOGE(RECPTPRINTER_SRV,  "Descriptor is not matched");
        return ERR_NAME_NOT_FOUND;
    }

    return CheckRequestCode(code,  data,  reply,  option);
}

int32_t RecptprinterSrvStub::CheckRequestCode(const uint32_t code, MessageParcel& data,
    MessageParcel& reply, MessageOption& option) {
    switch (code) {
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_GETPRINTFORMAT): {
            return GetPrintFormatStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_SETPRINTFORMAT): {
            return SetPrintFormatStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_GETDEVICESPEC): {
            return GetDeviceSpecStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_FEEDPAPER): {
            return FeedPaperStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_CUTPAPER): {
            return CutPaperStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDTEXT): {
            return AddTextStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDBITMAP): {
            return AddBitmapStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDQRCODE): {
            return AddQRCodeStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_ADDBARCODE): {
            return AddBarCodeStub(data, reply, option);
        }
        case static_cast<int>(IRecptprinterSrv::RECPTPRINTER_STARTPRINT): {
            return StartPrintStub(data, reply, option);
        }
        default: {
            return CashDeviceSrvStub::OnRemoteRequest(code, data, reply, option);
        }
    }
    return IPCObjectStub::OnRemoteRequest(code,  data,  reply,  option);
}


int32_t RecptprinterSrvStub::GetPrintFormatStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int ftt;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, ftt, E_READ_PARCEL_ERROR);
    int result = GetPrintFormat(handle, (PrintFormatType)ftt);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}
int32_t RecptprinterSrvStub::SetPrintFormatStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int ftt;
    int value = -1;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, ftt, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, value, E_READ_PARCEL_ERROR);

    SetPrintFormat(handle, (PrintFormatType)ftt, value);
    return ERR_OK;
}
int32_t RecptprinterSrvStub::GetDeviceSpecStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    DeviceSpec spec;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    GetDeviceSpec(handle, spec);
    WRITE_BUFFER_WITH_RET(reply, DeviceSpec, &spec, sizeof(spec), E_READ_PARCEL_ERROR);
    return ERR_OK;
}
int32_t RecptprinterSrvStub::FeedPaperStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int line = -1;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, line, E_READ_PARCEL_ERROR);

    int result = FeedPaper(handle, line);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}
int32_t RecptprinterSrvStub::CutPaperStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int line = -1;
    int mode = -1;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, line, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, mode, E_READ_PARCEL_ERROR);

    int result = CutPaper(handle, line, mode);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}
int32_t RecptprinterSrvStub::AddTextStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int x = -1;
    int y = -1;
    std::string text;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, x, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, y, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, String, text, E_READ_PARCEL_ERROR);

    int result = AddText(handle, x, y, text);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}
int32_t RecptprinterSrvStub::AddBitmapStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int x = -1;
    int y = -1;
    std::string lpath;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, x, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, y, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, String, lpath, E_READ_PARCEL_ERROR);

    int result = AddBitmap(handle, x, y, lpath);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}


int32_t RecptprinterSrvStub::AddQRCodeStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int x = -1;
    int y = -1;
    int w = 1;
    std::string qr;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, x, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, y, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, w, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, String, qr, E_READ_PARCEL_ERROR);


    int result = AddQRCode(handle, x, y, w, qr);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}
int32_t RecptprinterSrvStub::AddBarCodeStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int x = -1;
    int y = -1;
    const BarCodeSpec *spec;
    std::string bar;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, x, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, y, E_READ_PARCEL_ERROR);
    READ_BUFFER_WITH_RET(data, BarCodeSpec, spec, sizeof(BarCodeSpec));
    READ_PARCEL_WITH_RET(data, String, bar, E_READ_PARCEL_ERROR);

    int result = AddBarCode(handle, x, y, (BarCodeSpec&)*spec, bar);
    WRITE_PARCEL_WITH_RET(reply, Int32, result, E_WRITE_PARCEL_ERROR);

    return ERR_OK;
}

int32_t RecptprinterSrvStub::StartPrintStub(MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
    int handle = -1;
    int timeout;

    READ_PARCEL_WITH_RET(data, Int32, handle, E_READ_PARCEL_ERROR);
    READ_PARCEL_WITH_RET(data, Int32, timeout, E_READ_PARCEL_ERROR);
    sptr<IRemoteObject> remote = data.ReadRemoteObject();
    // sptr<IRecptprinterObserver> observer = iface_cast<IRecptprinterObserver>(remote);
    if (remote != nullptr) {
        proxy_ = iface_cast<RecptprinterObserverProxy>(remote);
    } else {
        proxy_ = nullptr;
    }

    RECPTPRINTER_HILOGD(RECPTPRINTER_SRV, "proxy_ is %{public}d", proxy_ != nullptr);
    StartPrint(handle, timeout, proxy_);
    return ERR_OK;
}

}  // namespace Finance
}  // namespace SwanLink
